/*
 * Created on Apr 28, 2004
 *
 * To change the template for this generated file go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
package abdn.graph.growl;

import java.awt.event.KeyEvent;
import java.net.URI;
import java.util.Iterator;
import java.util.Vector;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import abdn.graph.ontobrowser.ESDOntoBrowser;
import abdn.graph.ontobrowser.GUIPolicyEditor;
import abdn.graph.ontobrowser.OBNode;
import abdn.graph.ontobrowser.OBObjectNode;

import com.touchgraph.graphlayout.TGPanel;

/**
 * @author skrivov
 *
 * To change the template for this generated type comment go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
public class ObjectPropertyPanel extends JPanel {

  public static final String andComment = "Intersection of classes A, B, C,... is a set of all such instances that belong   to every class A, B, C,...";

  public static final String orComment = "Union of classes A, B, C,... is a set of all such instances that belong  to at least one class A, B, C,...";

  public static final String notComment = "Complement of class A is a set of all instances that do not belong to  A";

  public static final String oneofComment = "This is an enumeration - a   set of instances or data values pointed by argument arrows";

  static final String empty = "";

  private OBObjectNode node = null;

  private javax.swing.JLabel nameLabel = null;

  private javax.swing.JTextField nameTextField = null;

  private javax.swing.JLabel uriLabel = null;

  private javax.swing.JTextField uriText = null;

  private javax.swing.JLabel commentsLabel = null;

  private javax.swing.JTextPane commentsText = null;

  private ESDOntoBrowser esdOntoBrowser = null;

  private TGPanel tgPanel = null;

  private KRPolicyOWL krPolicy = null;

  private javax.swing.JComboBox nameComboBox = null;

  private javax.swing.JComboBox datatypeComboBox = null;

  private boolean editable = true;

  private JLabel jLabel = null;

  private JTextField labelTextField = null;

  /**
   * This is the default constructor
   */
  public ObjectPropertyPanel() {
    super();

    initialize();
  }

  /**
   * This method initializes this
   */
  private void initialize() {
    jLabel = new JLabel();
    this.setLayout(null);
    this.add(getNameLabel(), null);
    this.add(getNameTextField(), null);
    this.add(getUriLabel(), null);
    this.add(getUriText(), null);
    this.add(getCommentsLabel(), null);
    this.add(getCommentsText(), null);
    this.add(getNameComboBox(), null);
    this.add(getDatatypeComboBox(), null);
    setXSDTypes(getNameComboBox());
    setXSDTypes(getDatatypeComboBox());
    this.setSize(156, 252);
    this.setPreferredSize(new java.awt.Dimension(156, 252));
    jLabel.setBounds(7, 39, 103, 13);
    jLabel.setText("Label");
    this.add(jLabel, null);
    this.add(getLabelTextField(), null);
  }

  /**
   * This method initializes nameLabel
   *
   * @return javax.swing.JLabel
   */
  private javax.swing.JLabel getNameLabel() {
    if (nameLabel == null) {
      nameLabel = new javax.swing.JLabel();
      nameLabel.setBounds(7, 4, 101, 15);
      nameLabel.setText("Name");
    }
    return nameLabel;
  }

  /**
   * This method initializes nameTextField
   *
   * @return javax.swing.JTextField
   */
  private javax.swing.JTextField getNameTextField() {
    if (nameTextField == null) {
      nameTextField = new javax.swing.JTextField();
      nameTextField.setBounds(7, 20, 142, 15);
      /*
       * nameTextField .addCaretListener(new
       * javax.swing.event.CaretListener() { public void
       * caretUpdate(javax.swing.event.CaretEvent e) { updateNodeLabel(); }
       * });
       */
      nameTextField.addKeyListener(new java.awt.event.KeyAdapter() {
        public void keyPressed(java.awt.event.KeyEvent e) {
          //System.out.println("KeyEvent: " + e.toString() );
          if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            updateNodeName();
          }
          if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
            restoreNodeName();
          }
        }

      });

    }
    return nameTextField;
  }

  private void updateNodeName() {
    String ns = node.getNamespace();
    if (ns == null || ns.length() == 0) {
      String s = nameTextField.getText();
      String old = node.getName();
     /* if (!old.equals(s)) {
        node.setName(s);
        ( (GUIPolicyEditor) esdOntoBrowser.guiPolicy).changeNameNotification(
            node, old);
        tgPanel.repaint();
      }*/
    }
  }

  private void updateNodeLabel() {

    String s = labelTextField.getText();
    String old = node.getNodeLabel();
    /*if (!s.equals(old)) {
      node.setNodeLabel(s);
      ( (GUIPolicyEditor) esdOntoBrowser.guiPolicy).changeLabelNotification(
          node, old);
      tgPanel.repaint();
    }*/

  }

  private void restoreNodeName() {
    String newStr = nameTextField.getText();
    String s = node.getName();
    if (!newStr.equals(s)) {
      nameTextField.setText(s);
    }
  }

  private void restoreNodeLabel() {
    String newStr = labelTextField.getText();
    String s = node.getNodeLabel();
    if (!newStr.equals(s)) {
      labelTextField.setText(s);
    }
  }

  /**
   * @return OBObjectNode
   * @see OBObjectNode
   */
  public OBObjectNode getNode() {
    return node;
  }

  /**
   * @param n being the node to be set
   */
  public void setNode(OBObjectNode n) {
    if (getNameTextField().isVisible() && node != null) {
      updateNodeName();
      //updateNodeLabel();
    }
    this.node = n;
    getNameLabel().setVisible(true);
    jLabel.setVisible(false);
    getLabelTextField().setVisible(false);
    getUriLabel().setText("Namespace");
    if (node == null) { // clear the property pane when no node is selected
      getNameTextField().setVisible(true);
      getNameTextField().setText(null);
      getLabelTextField().setVisible(true);
      jLabel.setVisible(true);
      getLabelTextField().setText(null);
      getNameComboBox().setVisible(false);
      getDatatypeComboBox().setVisible(false);
      getUriText().setVisible(true);
      getUriText().setText(null);
      getCommentsText().setText(empty);
      return;
    }
    getNameTextField().setEditable(editable);
    getLabelTextField().setEditable(editable);
    if (node.objectCategory == RenderGrowl.OBJ_DATATYPE) {
      getNameTextField().setVisible(false);

      getNameComboBox().setVisible(true);
      //getNameComboBox().setEditable(true);
      getDatatypeComboBox().setVisible(false);
      //getDatatypeComboBox().setEditable(false);
      getUriText().setVisible(true);

    }
    else if (node.objectCategory == RenderGrowl.OBJ_DATAVALUE) {
      getNameTextField().setVisible(true);
      getNameComboBox().setVisible(false);
      //getLabelTextField().setVisible(false);
      getDatatypeComboBox().setVisible(true);
      //getDatatypeComboBox().setEditable(true);
      //			getNameComboBox().setEditable(false);

      getUriText().setVisible(false);

      getUriLabel().setText("Data Type");

    }
    else {
      getNameTextField().setVisible(true);
      getLabelTextField().setVisible(true);
      jLabel.setVisible(true);
      getNameComboBox().setVisible(false);
      getDatatypeComboBox().setVisible(false);
      getUriText().setVisible(true);
    }

    //getUriLabel().setText("URI Base");
    getUriText().setText("");
    if (node.objectCategory < 5) {
      getNameTextField().setText(KRPolicyOWL.stripNamespace(node.getName()));
      if (node.getNodeLabel() != null) {
        getLabelTextField().setText(KRPolicyOWL.stripNamespace(node.getNodeLabel()));
      }
      else {
        getLabelTextField().setText(null);
      }
      getCommentsText().setText(node.getHint());
      if (node.objectCategory != RenderGrowl.OBJ_DATAVALUE) {
        String ns;
        if ( (ns = node.getNamespace()) != null) {
          getUriText().setText( ns.length() == 0 ? RenderGrowl.defaultNS : ns);
        }
        if (ns != null && ns.length() > 0) {
          getNameTextField().setEditable(false);
          getLabelTextField().setEditable(false);
        }
      }
    }

    switch (node.objectCategory) {
      case RenderGrowl.OBJ_CLASS: {
        getNameLabel().setText("Class Name");

        break;
      }
      case RenderGrowl.OBJ_DATATYPE: {
        getNameComboBox().setSelectedItem(node.getLabel());
        getNameLabel().setText("Datatype Name");
        break;
      }
      case RenderGrowl.OBJ_INDIVIDUAL: {
        getNameLabel().setText("Individual Name");

        break;
      }
      case RenderGrowl.OBJ_DATAVALUE: {
        getNameLabel().setText("Data Value");
        String type;
        URI typeURI = node.getURI();
        if (typeURI == null) {
          type = "string";
        }
        else {
          type = typeURI.getFragment();
        }
        getDatatypeComboBox().setSelectedItem(type);
        break;
      }
      case RenderGrowl.OBJ_INTERSECTION: {
        getNameLabel().setVisible(false);
        getNameTextField().setVisible(false);
        getLabelTextField().setVisible(false);
        getUriLabel().setText("Anonymous Class");
        getUriText().setText(getOperatorName("intersection", node));
        getCommentsText().setText(andComment);
        break;
      }
      case RenderGrowl.OBJ_UNION: {
        getNameLabel().setVisible(false);
        getNameTextField().setVisible(false);
        getLabelTextField().setVisible(false);
        getUriLabel().setText("Anonymous Class");
        getUriText().setText(getOperatorName("union", node));
        getCommentsText().setText(orComment);
        break;
      }
      case RenderGrowl.OBJ_COMPLEMENT: {
        getNameLabel().setVisible(false);
        getNameTextField().setVisible(false);
        getLabelTextField().setVisible(false);
        getUriLabel().setText("Anonymous Class");
        getUriText().setText(getOperatorName("complement", node));
        getCommentsText().setText(notComment);
        break;
      }
      case RenderGrowl.OBJ_ONE_OF: {
        getNameLabel().setVisible(false);
        getNameTextField().setVisible(false);
        getLabelTextField().setVisible(false);
        getUriLabel().setText("Anonymous Class");
        getUriText().setText(getOperatorName("oneof", node));
        getCommentsText().setText(oneofComment);
        break;
      }
    }
  }

  public boolean updateNode() {

    if (node == null) {
      return true;
    }
    //update comments
    node.setHint(commentsText.getText());
    return true;

  }

  private String getOperatorName(String op, OBObjectNode n) {
    Vector args = n.getOutputs();
    String opName = op + "(";
    for (Iterator iter = args.iterator(); iter.hasNext(); ) {
      OBNode arg = (OBNode) iter.next();
      opName += arg.getLabel();
      if (!iter.hasNext()) {
        break;
      }
      else {
        opName += ",";
      }
    }
    opName += ")";
    return opName;
  }

  /**
   * This method initializes uriLabel
   *
   * @return javax.swing.JLabel
   */
  private javax.swing.JLabel getUriLabel() {
    if (uriLabel == null) {
      uriLabel = new javax.swing.JLabel();
      uriLabel.setBounds(7, 76, 99, 16);
      uriLabel.setText("Namespace");
    }
    return uriLabel;
  }

  /**
   * This method initializes uriText
   *
   * @return javax.swing.JTextField
   */
  private javax.swing.JTextField getUriText() {
    if (uriText == null) {
      uriText = new javax.swing.JTextField();
      uriText.setBounds(7, 95, 142, 15);
      uriText.setEditable(false);
    }
    return uriText;
  }

  /**
   * This method initializes commentsLabel
   *
   * @return javax.swing.JLabel
   */
  private javax.swing.JLabel getCommentsLabel() {
    if (commentsLabel == null) {
      commentsLabel = new javax.swing.JLabel();
      commentsLabel.setBounds(8, 118, 98, 15);
      commentsLabel.setText("Comments");
    }
    return commentsLabel;
  }

  /**
   * This method initializes commentsText
   *
   * @return javax.swing.JTextPane
   */
  private javax.swing.JTextPane getCommentsText() {
    if (commentsText == null) {
      commentsText = new javax.swing.JTextPane();
      commentsText.setBounds(8, 138, 140, 109);
      commentsText
          .addCaretListener(new javax.swing.event.CaretListener() {
        public void caretUpdate(javax.swing.event.CaretEvent e) {
          if (node != null) {
            node.setHint(commentsText.getText());
          }
        }
      });
    }
    return commentsText;
  }

  /**
   * @param ob being the panel
   */
  public void setOBPointer(ESDOntoBrowser ob) {
    esdOntoBrowser = ob;
    tgPanel = ob.getTGPanel();
    krPolicy = (KRPolicyOWL) ob.krPolicy;
    //System.out.println("EDSOntoBrowser: " + ob.toString() );
  }

  public void setEditable(boolean edit) {
    editable = edit;
    getNameTextField().setEditable(editable);
    getLabelTextField().setEditable(editable);
    getCommentsText().setEditable(editable);
    //getUriText().setEditable(editable);
  }

  /**
   * This method initializes nameComboBox
   *
   * @return javax.swing.JComboBox
   */
  private javax.swing.JComboBox getNameComboBox() {
    if (nameComboBox == null) {
      nameComboBox = new javax.swing.JComboBox();
      nameComboBox.setBounds(7, 20, 142, 15);
      nameComboBox.setVisible(false);
      nameComboBox.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent e) {
          //javax.swing.JComboBox cb =
          //	(javax.swing.JComboBox) e.getSource();
          if (node != null) {
            String dtype = (String) nameComboBox.getSelectedItem();
            node.setLabel(dtype);
            if (dtype.equalsIgnoreCase("Literal")) {
              setNamespace("rdfs");
            }
            else {
              setNamespace("xsd");
            }
            tgPanel.repaint();
          }
        }
      });
    }
    return nameComboBox;
  }

  private void setNamespace(String s) {
    node.setNamespace(s);
    getUriText().setText(s);

  }

  private void setXSDTypes(javax.swing.JComboBox cb) {
    cb.addItem("string");
    cb.addItem("normalizedString");
    cb.addItem("boolean");
    cb.addItem("decimal");
    cb.addItem("float");
    cb.addItem("double");
    cb.addItem("integer");
    cb.addItem("nonNegativeInteger");
    cb.addItem("positiveInteger");
    cb.addItem("nonPositiveInteger");
    cb.addItem("negativeInteger");
    cb.addItem("long");
    cb.addItem("int");
    cb.addItem("short");
    cb.addItem("byte");
    cb.addItem("unsignedLong");
    cb.addItem("unsignedInt");
    cb.addItem("unsignedShort");
    cb.addItem("unsignedByte");

    cb.addItem("hexBinary");
    cb.addItem("base64Binary");

    cb.addItem("dateTime");
    cb.addItem("time");
    cb.addItem("date");
    cb.addItem("gYearMonth");
    cb.addItem("gYear");
    cb.addItem("gMonthDay");
    cb.addItem("gDay");
    cb.addItem("gMonth");
    cb.addItem("anyURI");
    cb.addItem("token");

    cb.addItem("language");
    cb.addItem("NMTOKEN");
    cb.addItem("Name");
    cb.addItem("NCName");

    cb.addItem("Literal");

  }

  /**
   * This method initializes datatypeComboBox
   *
   * @return javax.swing.JComboBox
   */
  private javax.swing.JComboBox getDatatypeComboBox() {
    if (datatypeComboBox == null) {
      datatypeComboBox = new javax.swing.JComboBox();
      datatypeComboBox.setBounds(7, 95, 142, 15);
      datatypeComboBox.setVisible(false);
      datatypeComboBox
          .addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent e) {
          if (node != null) {
            OWLMetadata metadata = ( (KRPolicyOWL) esdOntoBrowser.krPolicy)
                .getMetadata();
            String dtype = (String) datatypeComboBox
                .getSelectedItem();
            if (!node.getLabel().equals(dtype)) {
              //              node.setNamespace(dtype);
              String type = metadata
                  .getTypeShortForm(dtype);
              node
                  .setURI(metadata
                          .uriFromShortForm(type));
              tgPanel.repaint();
            }
          }
        }
      });
    }
    return datatypeComboBox;
  }

  /**
   * This method initializes labelTextField
   *
   * @return javax.swing.JTextField
   */
  private JTextField getLabelTextField() {
    if (labelTextField == null) {
      labelTextField = new JTextField();
      labelTextField.setBounds(7, 55, 142, 15);
      labelTextField.addKeyListener(new java.awt.event.KeyAdapter() {
        public void keyPressed(java.awt.event.KeyEvent e) {
          if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            updateNodeLabel();
          }
          if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
            restoreNodeLabel();
          }
        }
      });
    }
    return labelTextField;
  }
} //  @jve:visual-info decl-index=0 visual-constraint="10,10"
